nestedsvm: update rip on invlpga intercept
authorChristoph Egger <Christoph.Egger@amd.com>
Thu, 12 May 2011 08:00:46 +0000 (09:00 +0100)
committerChristoph Egger <Christoph.Egger@amd.com>
Thu, 12 May 2011 08:00:46 +0000 (09:00 +0100)
Fixes endless loop.

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
xen/arch/x86/hvm/svm/emulate.c
xen/arch/x86/hvm/svm/svm.c
xen/include/asm-x86/hvm/svm/emulate.h

index 16f9c2b92fb78163b5b00eb343a2d9a34f000e89..6000bffd5311f72843235d22e8daa5080c459e39 100644 (file)
@@ -107,6 +107,7 @@ MAKE_INSTR(VMLOAD, 3, 0x0f, 0x01, 0xda);
 MAKE_INSTR(VMSAVE, 3, 0x0f, 0x01, 0xdb);
 MAKE_INSTR(STGI,   3, 0x0f, 0x01, 0xdc);
 MAKE_INSTR(CLGI,   3, 0x0f, 0x01, 0xdd);
+MAKE_INSTR(INVLPGA,3, 0x0f, 0x01, 0xdf);
 
 static const u8 *opc_bytes[INSTR_MAX_COUNT] = 
 {
@@ -126,6 +127,7 @@ static const u8 *opc_bytes[INSTR_MAX_COUNT] =
     [INSTR_VMSAVE] = OPCODE_VMSAVE,
     [INSTR_STGI]   = OPCODE_STGI,
     [INSTR_CLGI]   = OPCODE_CLGI,
+    [INSTR_INVLPGA] = OPCODE_INVLPGA,
 };
 
 static int fetch(struct vcpu *v, u8 *buf, unsigned long addr, int len)
index f5591f779cc0edd14ef3d165e6e9b9e839c92663..b34289781260206c0a756d5d7840a79f86288d96 100644 (file)
@@ -2061,7 +2061,10 @@ asmlinkage void svm_vmexit_handler(struct cpu_user_regs *regs)
         break;
 
     case VMEXIT_INVLPGA:
+        if ( (inst_len = __get_instruction_length(v, INSTR_INVLPGA)) == 0 )
+            break;
         svm_invlpga_intercept(v, regs->eax, regs->ecx);
+        __update_guest_eip(regs, inst_len);
         break;
 
     case VMEXIT_VMMCALL:
index 78e9dd0a684cd3834ecdd27792190bec81c50c44..7d2677fa07f6c3030519013158b9c3508684e7bb 100644 (file)
@@ -38,6 +38,7 @@ enum instruction_index {
     INSTR_VMSAVE,
     INSTR_STGI,
     INSTR_CLGI,
+    INSTR_INVLPGA,
     INSTR_MAX_COUNT /* Must be last - Number of instructions supported */
 };